import java.util.HashMap;
import java.util.List;


public class ClusteringEvaluator extends ClusteringEvaluatorBase {
	public static class Results {
		public int totalAnnotatedGenes;
		public int totalGenesInClustersWDominantAnnot;
	}
	
	private AnnotationsManager _annotMgr;
	private HashMap<String, Gene> _geneMap;
	
	public ClusteringEvaluator(AnnotationsManager annotMgr, HashMap<String, Gene> geneMap) {
		_annotMgr = annotMgr;
		_geneMap = geneMap;
	}
	
	public void set_annotMgr(AnnotationsManager _annotMgr) {
		this._annotMgr = _annotMgr;
	}

	public AnnotationsManager get_annotMgr() {
		return _annotMgr;
	}
	
	public void set_geneMap(HashMap<String, Gene> _geneMap) {
		this._geneMap = _geneMap;
	}

	public HashMap<String, Gene> get_geneMap() {
		return _geneMap;
	}

	@Override
	public double evaluate(List<Cluster> clusters) {
		// Just execute the 'inner' evaluate and discard the out parameters. 
		return evaluate(clusters, null);
	}
	
	/**
	 * Evaluate what fraction of annotated genes appear in a cluster with their dominant annotation.
	 * @param clusters List of clusters.
	 * @param totalAnnotatedGenes out parameter - how many annotated genes exist in the system.
	 * @param totalGenesInClustersWDominantAnnot out parameter - how many annotated genes belong to a cluster annotated with their annotation.
	 * @return the fraction of annotated genes that appear in a cluster with their dominant annotation, or 0 in case of a problem
	 */
	public double evaluate(List<Cluster> clusters, Results results) {
		if ((get_annotMgr() == null) || (get_geneMap() == null)) {
			return 0.0;
		}
		
		int totalAnnotatedGenes = 0;
		int totalGenesInClustersWDominantAnnot = 0;
		
		for (Gene g: _geneMap.values()) {
			if (g.isAnnotated()) {
				totalAnnotatedGenes++;
			}
		}
		
		for (Cluster c: clusters) {
			totalGenesInClustersWDominantAnnot += c.countGenesWithDominantAnnotation(_annotMgr);
		}

		if (results != null) {
			results.totalAnnotatedGenes = totalAnnotatedGenes;
			results.totalGenesInClustersWDominantAnnot = totalGenesInClustersWDominantAnnot;
		}
		
		return (double)totalGenesInClustersWDominantAnnot / totalAnnotatedGenes;		
	}
}
